package com.example.mydy.utils;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Build;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
import android.util.Base64;
import android.util.Log;

import androidx.security.crypto.EncryptedSharedPreferences;
import androidx.security.crypto.MasterKey;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class SecurityUtils {
    private static final String TAG = "SecurityUtils";
    private static final String ALGORITHM = "AES";
    private static final String KEY_PREF_NAME = "SecurityPrefs";
    private static final String KEY_ENCRYPTION_KEY = "encryption_key";
    private static final int KEY_LENGTH = 16;
    private static final String ENCRYPTED_PREFS_NAME = "EncryptedMyAppPrefs";
    private static final String KEYSTORE_PROVIDER = "AndroidKeyStore";
    private static final String MASTER_KEY_ALIAS = "_androidx_security_master_key_";

    public static void encryptAndSave(Context context, String key, String value) {
        try {
            SecretKey secretKey = getOrCreateSecretKey(context);
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] encryptedBytes = cipher.doFinal(value.getBytes());
            String encryptedValue = Base64.encodeToString(encryptedBytes, Base64.DEFAULT);

            SharedPreferences.Editor editor = context.getSharedPreferences(KEY_PREF_NAME, Context.MODE_PRIVATE).edit();
            editor.putString(key, encryptedValue);
            editor.apply();
        } catch (Exception e) {
            Log.e(TAG, "Error encrypting data", e);
        }
    }

    public static String decryptAndGet(Context context, String key) {
        try {
            SharedPreferences prefs = context.getSharedPreferences(KEY_PREF_NAME, Context.MODE_PRIVATE);
            String encryptedValue = prefs.getString(key, null);
            if (encryptedValue == null) {
                return null;
            }

            SecretKey secretKey = getOrCreateSecretKey(context);
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            byte[] decryptedBytes = cipher.doFinal(Base64.decode(encryptedValue, Base64.DEFAULT));
            return new String(decryptedBytes);
        } catch (Exception e) {
            Log.e(TAG, "Error decrypting data", e);
            return null;
        }
    }

    private static SecretKey getOrCreateSecretKey(Context context) throws Exception {
        SharedPreferences prefs = context.getSharedPreferences(KEY_PREF_NAME, Context.MODE_PRIVATE);
        String keyString = prefs.getString(KEY_ENCRYPTION_KEY, null);

        if (keyString == null) {
            // 生成新的密钥
            byte[] keyBytes = new byte[KEY_LENGTH];
            for (int i = 0; i < KEY_LENGTH; i++) {
                keyBytes[i] = (byte) (Math.random() * 256);
            }
            keyString = Base64.encodeToString(keyBytes, Base64.DEFAULT);
            
            // 保存密钥
            SharedPreferences.Editor editor = prefs.edit();
            editor.putString(KEY_ENCRYPTION_KEY, keyString);
            editor.apply();
        }

        byte[] keyBytes = Base64.decode(keyString, Base64.DEFAULT);
        return new SecretKeySpec(keyBytes, ALGORITHM);
    }

    public static void clearEncryptedData(Context context) {
        try {
            SharedPreferences.Editor editor = context.getSharedPreferences(KEY_PREF_NAME, Context.MODE_PRIVATE).edit();
            editor.clear();
            editor.apply();
        } catch (Exception e) {
            Log.e(TAG, "Error clearing encrypted data", e);
        }
    }

    public static String hashPassword(String password) {
        try {
            java.security.MessageDigest md = java.security.MessageDigest.getInstance("SHA-256");
            byte[] hashedBytes = md.digest(password.getBytes());
            return Base64.encodeToString(hashedBytes, Base64.DEFAULT);
        } catch (Exception e) {
            Log.e(TAG, "Error hashing password", e);
            return null;
        }
    }

    public static boolean verifyPassword(String password, String hashedPassword) {
        String hashedInput = hashPassword(password);
        return hashedInput != null && hashedInput.equals(hashedPassword);
    }

    /**
     * 创建或获取加密的SharedPreferences实例
     */
    public static SharedPreferences getEncryptedSharedPreferences(Context context) {
        try {
            MasterKey masterKey = new MasterKey.Builder(context)
                    .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
                    .build();

            return EncryptedSharedPreferences.create(
                    context,
                    ENCRYPTED_PREFS_NAME,
                    masterKey,
                    EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
                    EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
            );
        } catch (GeneralSecurityException | IOException e) {
            Log.e(TAG, "创建加密SharedPreferences失败，回退到普通SharedPreferences", e);
            return context.getSharedPreferences("MyAppPrefs", Context.MODE_PRIVATE);
        }
    }

    /**
     * 将现有SharedPreferences数据迁移到加密SharedPreferences
     */
    public static void migrateToEncryptedPrefs(Context context) {
        SharedPreferences oldPrefs = context.getSharedPreferences("MyAppPrefs", Context.MODE_PRIVATE);
        SharedPreferences encryptedPrefs = getEncryptedSharedPreferences(context);
        
        // 检查是否已经迁移
        if (encryptedPrefs.getBoolean("has_migrated", false)) {
            return;
        }
        
        SharedPreferences.Editor editor = encryptedPrefs.edit();
        
        // 迁移所有键值对
        for (String key : oldPrefs.getAll().keySet()) {
            Object value = oldPrefs.getAll().get(key);
            if (value instanceof String) {
                editor.putString(key, (String) value);
            } else if (value instanceof Boolean) {
                editor.putBoolean(key, (Boolean) value);
            } else if (value instanceof Integer) {
                editor.putInt(key, (Integer) value);
            } else if (value instanceof Long) {
                editor.putLong(key, (Long) value);
            } else if (value instanceof Float) {
                editor.putFloat(key, (Float) value);
            }
        }
        
        // 标记为已迁移
        editor.putBoolean("has_migrated", true);
        editor.apply();
        
        // 清除旧的SharedPreferences
        oldPrefs.edit().clear().apply();
    }

    /**
     * 使用安全哈希算法对密码进行哈希处理
     */
    public static String hashPassword(String password, String salt) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            md.update(salt.getBytes());
            byte[] hashedPassword = md.digest(password.getBytes());
            return Base64.encodeToString(hashedPassword, Base64.NO_WRAP);
        } catch (NoSuchAlgorithmException e) {
            Log.e(TAG, "哈希密码失败", e);
            return null;
        }
    }

    /**
     * 生成随机盐值
     */
    public static String generateSalt() {
        SecureRandom random = new SecureRandom();
        byte[] salt = new byte[16];
        random.nextBytes(salt);
        return Base64.encodeToString(salt, Base64.NO_WRAP);
    }
    
    /**
     * 安全擦除敏感数据数组
     */
    public static void clearArray(byte[] array) {
        if (array != null) {
            Arrays.fill(array, (byte) 0);
        }
    }
    
    /**
     * 检查设备是否支持加密SharedPreferences
     */
    public static boolean isEncryptedPrefsSupported() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
    }
} 